package org.xiezc.entity;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;
import org.xiezc.util.BaseUtil;
import org.xiezc.util.StrUtil;

/**
 * 微信的配置实体类
 * 
 * @author xiezc
 *
 */
public class WechatConfig {

	private ReadWriteLock myLock = new ReentrantReadWriteLock();

	private WechatConfig() {
		super();
	}

	private static WechatConfig wechatConfig = null;

	/**
	 * 单例模式
	 * 
	 * @return
	 */
	public static WechatConfig getInstance() {
		if (wechatConfig == null) {
			wechatConfig = new WechatConfig();
		}
		return wechatConfig;
	}

	public static Logger log = Logger.getLogger(WechatConfig.class);

	private SimpleDateFormat sdf = new SimpleDateFormat("MMddHHmmss");
	private String appId;
	private String appSecret;
	private String url;
	private String token;
	private String encodingAESKey;
	// 消息的加解密方式，有三种，开发时使用明文模式 ：noEncrypt,混合模式：mix,加密模式：aes
	private String encryptType;

	private int sleepTime = 3600;

	private String accessToken;
	private String requestTime;

	/**
	 * check accesstoken whether or not past due
	 * 
	 * @return
	 */
	public boolean checkAccessToken() {
		try {
			myLock.readLock().lock();
			if (StrUtil.isNOB(requestTime)) {
				return false;
			}
			Integer now = Integer.parseInt(sdf.format(new Date()));
			Integer oldTime = Integer.parseInt(requestTime);
			if (now - oldTime >= sleepTime) {
				return false;
			}
			return true;
		} catch (NumberFormatException e) {
			e.printStackTrace();
			return false;
		} finally {
			myLock.readLock().unlock();
		}
	}

	/**
	 * update accesstoken
	 */
	public String updateAccessToken() {
		if (checkAccessToken()) {
			return accessToken;
		}
		String url = "https://api.weixin.qq.com/cgi-bin/token";
		String param = "grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;
		String result = BaseUtil.sendGet(url, param);

		String pattern = "(.*)(\"access_token\":\")(.*)(\",\"expires_in\":)(.*)";
		Pattern r = Pattern.compile(pattern);
		Matcher m = r.matcher(result);
		if (m.find()) {
			try {
				myLock.readLock().lock();
				accessToken = m.group(3);
				requestTime = sdf.format(new Date());
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				myLock.readLock().unlock();
			}
		} else {
			log.error("updateAccessToken is failure");
		}
		return accessToken;
	}

	public String getAppId() {
		return appId;
	}

	public void setAppId(String appId) {
		this.appId = appId;
	}

	public String getAppSecret() {
		return appSecret;
	}

	public void setAppSecret(String appSecret) {
		this.appSecret = appSecret;
	}

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getToken() {
		return token;
	}

	public void setToken(String token) {
		this.token = token;
	}

	public String getEncodingAESKey() {
		return encodingAESKey;
	}

	public void setEncodingAESKey(String encodingAESKey) {
		this.encodingAESKey = encodingAESKey;
	}

	public String getEncryptType() {
		return encryptType;
	}

	public void setEncryptType(String encryptType) {
		this.encryptType = encryptType;
	}

	public SimpleDateFormat getSdf() {
		return sdf;
	}

	public void setSdf(SimpleDateFormat sdf) {
		this.sdf = sdf;
	}

	public int getSleepTime() {
		return sleepTime;
	}

	public void setSleepTime(int sleepTime) {
		this.sleepTime = sleepTime;
	}

	public String getAccessToken() {
		return accessToken;
	}

	public void setAccessToken(String accessToken) {
		this.accessToken = accessToken;
	}

	public String getRequestTime() {
		return requestTime;
	}

	public void setRequestTime(String requestTime) {
		this.requestTime = requestTime;
	}

}
